
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Security.Cryptography;
using System.Diagnostics;
using System.Net.Sockets;
using System.Text;
using System.IO;
namespace Iridium
{
	public class gg_login80 : ggPacketToSend 
	{
		public int uin = 0;
		byte[] language = Encoding.UTF8.GetBytes("pl");
		public int status = (int)ggStates.GG_STATUS_AVAIL;
		public int flags = 0;
		int features = (int)ggFeatures.ACK + (int)ggFeatures.ATRIBUTES + (int)ggFeatures.BETA80 + (int)ggFeatures.LOGIN80 + (int)ggFeatures.MSG80 + (int)ggFeatures.MULTILOGON + (int)ggFeatures.NEWCLIENTS + (int)ggFeatures.NEWSTATES + (int)ggFeatures.NOBETA80 + (int)ggFeatures.NOTIFY;
		int local_ip = 0;
		short local_port = 0;
		int external_ip = 0;
		short external_port = 0;
		//rozmiar max obrazka w kb
		byte image_size = 0xFF;
		byte unknown1 = 0x64;
		int version_len = (ggConst.use_version == 8 ? ggConst.version_8_str.Length : ggConst.version_10_str.Length);
		byte[] version = Encoding.UTF8.GetBytes((ggConst.use_version == 8 ? ggConst.version_8_str : ggConst.version_10_str));
		int description_size = 0;
		public byte[] description = null;
		public string password = "";
		public uint seed = 0;
		public gg_login80(NetworkStream ns) : base(ns) {}
		//http://ggsharp.codeplex.com/SourceControl/changeset/view/7768#157290
		private byte[] GetSHA1Hash(string password, uint seed)
		{
			var passwordBytes = Encoding.UTF8.GetBytes(password);
			var seedBytes = BitConverter.GetBytes(seed);

			//create one byte array
			var bytes = new byte[passwordBytes.Length + seedBytes.Length];
			passwordBytes.CopyTo(bytes, 0);
			seedBytes.CopyTo(bytes, passwordBytes.Length);

			var sha1Hash = SHA1Managed.Create();
			return sha1Hash.ComputeHash(bytes);
		}

		//http://code.google.com/p/dotgadu/source/browse/trunk/dotgadu/src/GaduLogin.cs
		private uint getHash(String password, uint seed)
		{
			uint x, y, z;

			y = seed;

			int p = 0;
			for (x = 0; p < password.Length; p++)
			{
				x = (x & 0xffffff00) | Convert.ToByte(password[p]);
				y ^= x;
				y += x;
				x <<= 8;
				y ^= x;
				x <<= 8;
				y -= x;
				x <<= 8;
				y ^= x;

				z = y & 0x1f;
				y = (uint)((uint)y << (int)z) | (uint)((uint)y >> (int)(32 - z));
			}
			return y;
		}

		public bool sendPacket(NetworkStream ns)
		{
			this.packetType = ggPacketTypes_Send.gg_login80;

			//        AddObject(packetType)

			//Dim lol As Integer = 4 + 2 + 1 + 4 + 4 + 64 + 4 + 4 + 2 + 4 + 2 + 1 + 1 + 4 + Len(version) + 4 + Len(description)
			//  ns.Write(CInt(packetType))
			// ns.Write(lol)


			
			bw.Write(uin);
			bw.Write(language);
			bw.Write((byte)0x02); //hash-type
			if (description != null)
				description_size = description.Length;
			byte[] _hash = GetSHA1Hash(password, seed);
			bw.Write(_hash);
			for (int i = 0; i < 64 - _hash.Length; i++)
				bw.Write((byte)0);
			bw.Write(Convert.ToInt32(status));
			bw.Write(Convert.ToInt32(flags));
			bw.Write(Convert.ToInt32(features));
			bw.Write(local_ip);
			bw.Write(Convert.ToInt16(local_port));
			bw.Write(external_ip);
			bw.Write(Convert.ToInt16(external_port));
			bw.Write(image_size);
			bw.Write(unknown1);
			bw.Write(version_len);
			bw.Write(version);
			bw.Write(description_size);
			if (description != null)
				bw.Write(description);


			bool lol = this.Send(ns);
			return lol;
		}
	}
}